package com.qixiaobao.web.controller.nondirect.settle;

import com.qixiaobao.common.annotation.Log;
import com.qixiaobao.common.annotation.RepeatSubmit;
import com.qixiaobao.common.core.domain.AjaxResult;
import com.qixiaobao.common.core.page.TableDataInfo;
import com.qixiaobao.common.enums.BusinessType;
import com.qixiaobao.common.enums.InsureFeeStatusEnum;
import com.qixiaobao.common.exception.UtilException;
import com.qixiaobao.common.utils.StringUtils;
import com.qixiaobao.common.utils.easyExcel.EasyExcelUtil;
import com.qixiaobao.nondirect.settle.domain.InsureFee;
import com.qixiaobao.nondirect.settle.domain.SettlementStatistic;
import com.qixiaobao.nondirect.settle.domain.SupplyPremiumPaid;
import com.qixiaobao.nondirect.settle.domain.dto.InsureFeeDTO;
import com.qixiaobao.nondirect.settle.domain.dto.NonDirectWaitDTO;
import com.qixiaobao.nondirect.settle.domain.dto.SettlementStatisticDTO;
import com.qixiaobao.nondirect.settle.domain.dto.SupplyPremiumPaidDTO;
import com.qixiaobao.nondirect.settle.domain.vo.InsureFeeChargeVO;
import com.qixiaobao.nondirect.settle.domain.vo.NonDirectSettleWaitVO;
import com.qixiaobao.nondirect.settle.domain.vo.SettlementStatisticVO;
import com.qixiaobao.nondirect.settle.domain.vo.SupplyPremiumPaidVO;
import com.qixiaobao.nondirect.settle.service.IInsureFeeService;
import com.qixiaobao.nondirect.settle.service.INonDirectWaitService;
import com.qixiaobao.nondirect.settle.service.ISettlementStatisticService;
import com.qixiaobao.nondirect.settle.service.ISupplyPremiumPaidService;
import com.qixiaobao.system.domain.dto.ChargeDTO;
import com.qixiaobao.system.domain.dto.PersonDTO;
import com.qixiaobao.web.controller.core.controller.BaseController;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description 非直投结算管理
 * @Author yangxm
 * @Date 2025/6/27 8:48
 */
@RestController
@RequestMapping("/nonDirect")
public class NonDirectSettleController extends BaseController {

    @Autowired
    private INonDirectWaitService nonDirectWaitService;
    @Autowired
    private IInsureFeeService insureFeeService;
    @Autowired
    private ISupplyPremiumPaidService supplyPremiumPaidService;
    @Autowired
    private ISettlementStatisticService settlementStatisticService;


    /**
     * @Description 待结算列表
     * @Author yangxm
     * @Date 2025/6/27 14:44
     * @param nonDirectWaitDTO
     * @return com.qixiaobao.common.core.page.TableDataInfo
     */
    @GetMapping("/wait/settle/list")
    public TableDataInfo waitSettleList(NonDirectWaitDTO nonDirectWaitDTO) {
        nonDirectWaitDTO.setNoPermissionSupplyIdList(checkPermission());
        startPage();
        return getDataTable(nonDirectWaitService.selectWaitSettleList(nonDirectWaitDTO));
    }

    /**
     * @Description 待结算-结算人数和费用总计统计
     * @Author yangxm
     * @Date 2025/6/27 14:56
     * @param nonDirectWaitDTO 
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @GetMapping("/wait/settle/total")
    public AjaxResult waitSettleTotal(NonDirectWaitDTO nonDirectWaitDTO){
        nonDirectWaitDTO.setNoPermissionSupplyIdList(checkPermission());
        return success(nonDirectWaitService.selectWaitSettleTotal(nonDirectWaitDTO));
    }

    /**
     * @Description 待结算导出
     * @Author yangxm
     * @Date 2025/6/27 14:44
     * @param nonDirectWaitDTO
     * @param response
     */
    @Log(title = "非直投结算管理-待结算", businessType = BusinessType.EXPORT)
    @GetMapping("/wait/settle/export")
    public void waitSettleExport(NonDirectWaitDTO nonDirectWaitDTO, HttpServletResponse response){
        nonDirectWaitDTO.setNoPermissionSupplyIdList(checkPermission());
        List<NonDirectSettleWaitVO> list = nonDirectWaitService.selectWaitSettleList(nonDirectWaitDTO);
        try {
            EasyExcelUtil.writeExcel(response, list, NonDirectSettleWaitVO.class, "非直投待结算", "sheet1");
        } catch (IOException e) {
            throw new UtilException("导出失败：" + e.getMessage());
        }
    }

    /**
     * @Description 非直投结算管理-待结算 - 人员详情
     * @Author yangxm
     * @Date 2025/6/27 14:50
     * @param personDTO
     * @return com.qixiaobao.common.core.page.TableDataInfo
     */
    @GetMapping("/wait/settle/person/list")
    public TableDataInfo waitSettlePersonList(PersonDTO personDTO){
        startPage();
        return getDataTable(nonDirectWaitService.selectWaitSettlePersonList(personDTO));
    }

    /**
     * @Description 非直投结算管理-待结算 - 结算
     * @Author yangxm
     * @Date 2025/6/27 14:50
     * @param insureFee
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @RepeatSubmit
    @Log(title = "非直投结算管理-待结算", businessType = BusinessType.SETTLEMENT)
    @PostMapping("/wait/settle")
    public AjaxResult settle(@RequestBody InsureFee insureFee){
        return toAjax(nonDirectWaitService.settle(insureFee));
    }

    /**
     * @Description 非直投结算管理-待结算 - 一键结算
     * @Author yangxm
     * @Date 2025/6/27 14:50
     * @param nonDirectWaitDTO
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @RepeatSubmit
    @Log(title = "非直投结算管理-待结算", businessType = BusinessType.SETTLEMENT_ALL)
    @PostMapping("/wait/settle/all")
    public AjaxResult settleAll(@RequestBody NonDirectWaitDTO nonDirectWaitDTO){
        nonDirectWaitDTO.setNoPermissionSupplyIdList(checkPermission());
        return toAjax(nonDirectWaitService.settleAll(nonDirectWaitDTO));
    }

    /**
     * @Description 待支付、已结算列表
     * @Author yangxm
     * @Date 2025/6/27 16:12
     * @param insureFeeDTO
     * @return com.qixiaobao.common.core.page.TableDataInfo
     */
    @GetMapping("/insureFee/list")
    public TableDataInfo insureFeeList(InsureFeeDTO insureFeeDTO){
        insureFeeDTO.setNoPermissionSupplyIdList(checkPermission());
        return getDataTable(insureFeeService.selectInsureFeeList(insureFeeDTO));
    }

    /**
     * @Description 待支付、已结算 - 结算人数和费用总计统计
     * @Author yangxm
     * @Date 2025/6/30 13:34
     * @param insureFeeDTO
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @GetMapping("/insureFee/total")
    public AjaxResult insureFeeTotal(InsureFeeDTO insureFeeDTO){
        insureFeeDTO.setNoPermissionSupplyIdList(checkPermission());
        return success(insureFeeService.selectInsureFeeTotal(insureFeeDTO));
    }

    /**
     * @Description 待支付、已结算 - 导出
     * @Author yangxm
     * @Date 2025/6/27 16:12
     * @param insureFeeDTO
     * @param response
     */
    @Log(title = "非直投结算管理-待支付、已结算", businessType = BusinessType.EXPORT)
    @GetMapping("/insureFee/export")
    public void insureFeeExport(InsureFeeDTO insureFeeDTO, HttpServletResponse response){
        insureFeeDTO.setNoPermissionSupplyIdList(checkPermission());
        insureFeeService.insureFeeExport(insureFeeDTO, response);
    }


    /**
     * @Description 待支付、已结算 - 费用详情列表
     * @Author yangxm
     * @Date 2025/6/27 16:12
     * @param chargeDTO
     * @return com.qixiaobao.common.core.page.TableDataInfo
     */
    @GetMapping("/insureFee/charge/list")
    public TableDataInfo insureFeeChargeList(ChargeDTO chargeDTO){
        return getDataTable(insureFeeService.selectInsureFeeChargeList(chargeDTO));
    }

    /**
     * @Description 待支付、已结算 - 费用详情列表导出
     * @Author yangxm
     * @Date 2025/6/27 16:12
     * @param chargeDTO
     * @param response
     */
    @Log(title = "非直投结算管理-待支付、已结算", businessType = BusinessType.EXPORT, businessKey = "详情")
    @GetMapping("/insureFee/charge/export")
    public void insureFeeChargeExport(ChargeDTO chargeDTO, HttpServletResponse response){
        if (chargeDTO.getInsureFeeId() == null){
            throw new UtilException("参数：保费ID不能为空！");
        }
        if (StringUtils.isBlank(chargeDTO.getInsureFeeStatus())){
            throw new UtilException("参数：保费结算状态不能为空！");
        }
        String insureFeeStatus = chargeDTO.getInsureFeeStatus();
        //用枚举判断状态是否有效
        if (!InsureFeeStatusEnum.isValidStatus(insureFeeStatus)) {
            throw new UtilException("参数：保费结算状态错误！");
        }
        List<InsureFeeChargeVO> list = insureFeeService.selectInsureFeeChargeList(chargeDTO);
        try {
            EasyExcelUtil.writeExcel(response, list, InsureFeeChargeVO.class, "非直投结算管理-待支付详情", "sheet1");
        } catch (IOException e) {
            throw new UtilException("导出失败：" + e.getMessage());
        }
    }


    /**
     * @Description 待支付 - 修改保费归属期
     * @Author yangxm
     * @Date 2025/7/1 9:40
     * @param insureFeeDTO 
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @RepeatSubmit
    @Log(title = "非直投结算管理-待支付", businessType = BusinessType.UPDATE, businessKey = "保费归属期")
    @PutMapping("/insureFee/wait/updateInsureFeeMonth")
    public AjaxResult updateWaitPayInsureFeeMonth(@RequestBody InsureFeeDTO insureFeeDTO){
        return toAjax(insureFeeService.updateInsureFeeMonth(insureFeeDTO));
    }

    /**
     * @Description 待支付、已结算 - 修改备注
     * @Author yangxm
     * @Date 2025/7/1 9:48
     * @param insureFeeDTO
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @RepeatSubmit
    @Log(title = "非直投结算管理-待支付、已结算", businessType = BusinessType.UPDATE, businessKey = "备注")
    @PutMapping("/insureFee/updateRemark")
    public AjaxResult updateRemark(@RequestBody InsureFeeDTO insureFeeDTO){
        return toAjax(insureFeeService.updateRemark(insureFeeDTO));
    }

    /**
     * @Description 待支付、已结算 - 一键下载凭证
     * @Author yangxm
     * @Date 2025/7/1 13:07
     * @param insureFeeDTO 
     * @return com.qixiaobao.common.core.domain.AjaxResult
     * 根据筛选条件下载，供应商简称必选
     */
    @Log(title = "非直投结算管理", businessType = BusinessType.DOWNLOAD_RECEIPT)
    @GetMapping("/insureFee/downloadReceipt")
    public AjaxResult downloadReceipt(InsureFeeDTO insureFeeDTO){
        insureFeeService.downloadReceipt(insureFeeDTO);
        return AjaxResult.success();
    }

    /**
     * @Description 已结算 - 获取凭证列表
     * @Author yangxm
     * @Date 2025/7/1 13:49
     * @param insureFeeId 
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @GetMapping("/insureFee/receipt/list/{insureFeeId}")
    public AjaxResult insureFeeReceiptList(@PathVariable Long insureFeeId){
        return success(insureFeeService.selectInsureFeeReceiptListByInsureFeeId(insureFeeId));
    }

    /**
     * @Description 已结算 - 修改预回票时间
     * @Author yangxm
     * @Date 2025/7/1 14:11
     * @param insureFeeDTO
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @Log(title = "非直投结算管理-已结算", businessType = BusinessType.UPDATE, businessKey = "预回票时间")
    @PutMapping("/insureFee/updateInvoiceReturnDate")
    public AjaxResult updateInvoiceReturnDate(@RequestBody InsureFeeDTO insureFeeDTO){
        return toAjax(insureFeeService.updateInvoiceReturnDate(insureFeeDTO));
    }

    /**
     * @Description 已付保费列表
     * @Author yangxm
     * @Date 2025/7/1 17:12
     * @param supplyPremiumPaidDTO
     * @return com.qixiaobao.common.core.page.TableDataInfo
     */
    @GetMapping("/supplyPremiumPaid/list")
    public TableDataInfo supplyPremiumPaidList(SupplyPremiumPaidDTO supplyPremiumPaidDTO){
        startPage();
        return getDataTable(supplyPremiumPaidService.selectSupplyPremiumPaidList(supplyPremiumPaidDTO));
    }

    /**
     * @Description 已付保费 - 支付金额总计
     * @Author yangxm
     * @Date 2025/7/1 17:12
     * @param supplyPremiumPaidDTO
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @GetMapping("/supplyPremiumPaid/total")
    public AjaxResult supplyPremiumPaidTotal(SupplyPremiumPaidDTO supplyPremiumPaidDTO){
        return success(supplyPremiumPaidService.selectSupplyPremiumPaidTotal(supplyPremiumPaidDTO));
    }

    /**
     * @Description 已付保费导出
     * @Author yangxm
     * @Date 2025/7/1 17:12
     * @param supplyPremiumPaidDTO
     * @param response
     */
    @Log(title = "非直投结算管理-已付保费", businessType = BusinessType.EXPORT)
    @GetMapping("/supplyPremiumPaid/export")
    public void supplyPremiumPaidExport(SupplyPremiumPaidDTO supplyPremiumPaidDTO, HttpServletResponse response){
        List<SupplyPremiumPaid> list = supplyPremiumPaidService.selectSupplyPremiumPaidList(supplyPremiumPaidDTO);
        List<SupplyPremiumPaidVO> excelList = new ArrayList<>();
        if (StringUtils.isNotEmpty(list)){
            SupplyPremiumPaidVO supplyPremiumPaidVO;
            SupplyPremiumPaid supplyPremiumPaid;
            for (int i = 0; i < list.size(); i++) {
                supplyPremiumPaid = list.get(i);
                supplyPremiumPaidVO = new SupplyPremiumPaidVO();
                BeanUtils.copyProperties(supplyPremiumPaid, supplyPremiumPaidVO);
                supplyPremiumPaidVO.setIndexNo(i + 1);
                excelList.add(supplyPremiumPaidVO);
            }
        }
        try {
            EasyExcelUtil.writeExcel(response, excelList, SupplyPremiumPaidVO.class, "非直投结算管理-已付保费", "sheet1");
        } catch (IOException e) {
            throw new UtilException("导出失败：" + e.getMessage());
        }
    }

    /**
     * @Description 已付保费 - 查看付款回单凭证
     * @Author yangxm
     * @Date 2025/7/2 8:45
     * @param id
     * @param insureFeeId 
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @GetMapping("/supplyPremiumPaid/receipt")
    public AjaxResult supplyPremiumPaidReceipt(@RequestParam(required = false)Long id,  @RequestParam(required = false) Long insureFeeId){
        if (id == null && insureFeeId == null){
            throw new IllegalArgumentException("缺少参数");
        }
        //若保费id不为空，则查询该保费的银行回单信息
        if (insureFeeId != null){
            InsureFee insureFee = insureFeeService.selectInsureFeeReceiptById(insureFeeId);
            if (insureFee == null){
                throw new IllegalArgumentException("保费信息不存在");
            }
            return AjaxResult.success(insureFee);
        }else {
            SupplyPremiumPaid supplyPremiumPaid = supplyPremiumPaidService.selectInsureFeeReceiptById(id);
            if (supplyPremiumPaid == null){
                throw new IllegalArgumentException("供应商已付保费不存在");
            }
            return AjaxResult.success(supplyPremiumPaid);
        }
    }

    /**
     * @Description 已付保费 - 修改备注
     * @Author yangxm
     * @Date 2025/7/2 8:59
     * @param supplyPremiumPaid
     * @return com.qixiaobao.common.core.domain.AjaxResult
     */
    @Log(title = "非直投结算管理-已付保费", businessType = BusinessType.UPDATE, businessKey = "付款备注")
    @PutMapping("/supplyPremiumPaid/updatePayRemark")
    public AjaxResult updateSupplyPremiumPaidPayRemark(@RequestBody SupplyPremiumPaid supplyPremiumPaid){
        return toAjax(supplyPremiumPaidService.updatePayRemark(supplyPremiumPaid));
    }

    /**
     * @Description 保费汇总
     * @Author yangxm
     * @Date 2025/7/2 9:06
     * @param settlementStatisticDTO
     * @return com.qixiaobao.common.core.page.TableDataInfo
     */
    @GetMapping("/settlementStatistic/list")
    public TableDataInfo settlementStatisticList(SettlementStatisticDTO settlementStatisticDTO) {
        startPage();
        List<SettlementStatistic> list = settlementStatisticService.statisticList(settlementStatisticDTO);
        return getDataTable(list);
    }

    /**
     * @Description 保费汇总 - 导出
     * @Author yangxm
     * @Date 2025/7/2 9:06
     * @param settlementStatisticDTO
     * @param response
     */
    @Log(title = "非直投结算管理-保费汇总", businessType = BusinessType.EXPORT)
    @GetMapping("/settlementStatistic/export")
    public void settlementStatisticExport (SettlementStatisticDTO settlementStatisticDTO, HttpServletResponse response) {
        List<SettlementStatistic> list = settlementStatisticService.statisticList(settlementStatisticDTO);
        List<SettlementStatisticVO> excelList = new ArrayList<>();
        if (StringUtils.isNotEmpty(list)){
            SettlementStatisticVO settlementStatisticVO;
            SettlementStatistic settlementStatistic;
            for (int i = 0; i < list.size(); i++) {
                settlementStatistic = list.get(i);
                settlementStatisticVO = new SettlementStatisticVO();
                BeanUtils.copyProperties(settlementStatistic, settlementStatisticVO);
                settlementStatisticVO.setIndex(i + 1);
                excelList.add(settlementStatisticVO);
            }
        }
        try {
            EasyExcelUtil.writeExcel(response, excelList, SettlementStatisticVO.class, "非直投结算管理-保费汇总", "sheet1");
        } catch (IOException e) {
            throw new UtilException("导出失败：" + e.getMessage());
        }
    }
}
